<?php

declare(strict_types=1);

namespace App\Model\Setting;

use App\Cache\RedisKey;
use App\Helpers\Helper;
use App\Helpers\RedisUtil;
use App\Model\User;
use App\Model\UserProfile;
use Hyperf\DbConnection\Db;
use Hyperf\DbConnection\Model\Model;
use Hyperf\Cache\Annotation\Cacheable;
use Hyperf\Utils\Context;
use Hyperf\Utils\Arr;
/**
 *  配置 - app功能隐藏
 */
class SettingAppHidden extends Model
{
    protected $table = 'setting_app_hidden';

    const FUNC_PUSH = 1;
    const FUNC_WECHAT = 2;
    const FUNC_MSG = 3;
    const FUNC_NAV = 4;

    //短视频入口
    const FUNC_VIDEO = 5;

    const FUNC_SEND_MSG_TIP = 6;

    const FUNC_GIFT = 7;

    protected $fillable = ['func_type', 'app_id', 'channel', 'version', 'week', 'end_time', 'begin_time', 'flag', 'hidden_un_know_city'];

    /**
     * 获取设置
     */
    static function getSetting($func = self::FUNC_PUSH)
    {
        $where = ['func_type' => $func, 'flag' => 1];
        $Hi = date('H:i');
        $items = self::where($where)->where('begin_time','<=',$Hi)->where('end_time','>=',$Hi)->get()->toArray();
        $setting = [];
        $week = date("w",time()) == 0 ? 7 : date("w",time());
        foreach ($items as $item) {
            $item_week = empty($item['week']) ? [] : json_decode($item['week'],true);
            if(in_array($week,$item_week)){
                $setting[] = [
                    'app_id' => explode(',', $item['app_id']),
                    'channel' => explode(',', $item['channel']),
                    'version' => $item['version'],
                    'hidden_un_know_city' => $item['hidden_un_know_city'],
                    'hidden_city' => empty($item['hidden_city']) ? [] : explode(',', $item['hidden_city']),
                ];
            }
        }
        return $setting;
    }

    static function getHiddeChannels($func = self::FUNC_PUSH)
    {
        $settings = SettingAppHidden::getSetting($func);
        $channels = $settings ? array_column($settings, 'channel') : [];
        $data = [];
        foreach ($channels as $channel) $data = array_merge($data, $channel);
        return $data;
    }

    /**
     * 是否隐藏app底部导航栏，审核时
     * @param $app_id int 包ID
     * @param $sys_version string 版本号
     * @param $app_channel int 渠道号
     * @return int
     */
    static function getAppExamine($app_id,$app_version,$app_channel)
    {

        //屏蔽特定地区
        $city = '';
        $limitHiddenCity = config('busi.limit_hidden_city');
        $limitHiddenCity = empty($limitHiddenCity) ? [] : explode(',',$limitHiddenCity);
        if(!empty($city) && in_array($city,$limitHiddenCity)) return 1;

        $where = ['func_type' => self::FUNC_NAV, 'flag' => 1];
        $Hi = date('H:i');
        $items = self::where($where)->where('begin_time','<=',$Hi)->where('end_time','>=',$Hi)->get()->toArray();
        $flag = 0;
        $week = date("w",time()) == 0 ? 7 : date("w",time());
        foreach ($items as $key=>$val){
            //判断是否在隐藏城市当中
            $item_week = empty($val['week']) ? [] : json_decode($val['week'],true);
            if(in_array($week,$item_week)){
                $appids = explode(',',$val['app_id']);
                $version = explode(',',$val['version']);
                $channel = explode(',',$val['channel']);
                $settingCity = empty($val['hidden_city']) ?  [] : explode(',',$val['hidden_city']);

                if(
                    in_array($app_id,$appids)
                    && in_array($app_version,$version)
                    && in_array($app_channel,$channel)
                    && (empty($city) || empty($settingCity) || (in_array($city,$settingCity)))
                ) {
                    $flag = 1;
                }

            }


        }
        return $flag;
    }

    static function getAppShortVideo($app_id, $app_version, $app_channel)
    {

        //屏蔽特定地区
        $city = '';
        $limitHiddenCity = config('busi.limit_hidden_city');
        $limitHiddenCity = empty($limitHiddenCity) ? [] : explode(',', $limitHiddenCity);
        if (!empty($city) && in_array($city, $limitHiddenCity)) return 1;

        $where = ['func_type' => self::FUNC_VIDEO, 'flag' => 1];
        $Hi = date('H:i');
        $items = self::where($where)->where('begin_time', '<=', $Hi)->where('end_time', '>=', $Hi)->get()->toArray();
        $flag = 0;
        $week = date("w", time()) == 0 ? 7 : date("w", time());
        foreach ($items as $key => $val) {
            //判断是否在隐藏城市当中
            $item_week = empty($val['week']) ? [] : json_decode($val['week'], true);
            if (in_array($week, $item_week)) {
                $appids = explode(',', $val['app_id']);
                $version = explode(',', $val['version']);
                $channel = explode(',', $val['channel']);
                $settingCity = empty($val['hidden_city']) ? [] : explode(',', $val['hidden_city']);

                if (
                    in_array($app_id, $appids)
                    && in_array($app_version, $version)
                    && in_array($app_channel, $channel)
                    && (empty($city) || empty($settingCity) || (in_array($city, $settingCity)))
                ) {
                    $flag = 1;
                }

            }


        }
        return $flag;
    }

    /**
     * @Cacheable(prefix="user_forbidden_users", ttl=20,value="_#{func_type}", listener="user_forbidden_users")
     * 获取被屏蔽的用户ID
     */
    static function getForbiddenUsers($func_type = self::FUNC_PUSH)
    {
        $funcType = empty($func_type) ? self::FUNC_PUSH : $func_type;

        $channels = self::getSetting($funcType);
        $where = [];
        //屏蔽特定地区
        $limitHiddenCity = config('busi.limit_hidden_city_string');
        $limitHiddenCity = empty($limitHiddenCity) ? [] : explode(',',$limitHiddenCity);

        foreach ($channels as $key => $item) {
            $channelId = implode(',', $item['channel']);
            $hiddenCity = $item['hidden_city'];
//            if(empty($hiddenCity)){
//                $where[] = "(t_user.cur_channel in({$channelId}) and t_user.app_version='" . $item['version'] . "')";
//            }else{
//                $city = [];
//                foreach ($hiddenCity as $key=>$val){
//                    $city[] = "'{$val}'";
//                }
//                $city = implode(',',$city);
//
//                $where[] = "(t_user.cur_channel in({$channelId}) and t_user.app_version='" . $item['version'] . "' and t_user_profile.locate_city in({$city}) )";
//            }
            $where[] = "(t_user.cur_channel in({$channelId}) and t_user.version='" . $item['version'] . "')";
        }


        $ids = Db::table('user')->join('user_profile','user.id','=','user_profile.user_id')
            ->where(function ($query) use($where){
                $sql = " t_user_profile.gender=1 and t_user_profile.online=1";
                $query->whereRaw($sql);
                if(!empty($where)){
                    $where = '(' . implode(' OR ', $where) . ')';
                    $query->whereRaw($where);
                }
            })->orderBy('user_profile.online', 'desc')
            ->orderBy('user_profile.user_id', 'desc')
            ->limit(400)->pluck('user.id')->toArray();;
        return $ids;
    }

    /**
     * 获取屏蔽的查询条件
     * @param int $func 屏蔽的条件类型
     */
    public static function getHiddenWhere($func = self::FUNC_PUSH)
    {
        $setting = self::getSetting($func);

        $item = [];

        $where = ' 1 ';
        foreach ($setting as $key => $value){
            $wData= [];
            //应用ID
            if ($value['app_id']) {
                $app_id = implode(',',$value['app_id']);
//                $wData[] = " t_user.app_id not in({$app_id})";
            }

            //渠道
            if (!empty($value['channel'])) {
                $curChannel  = implode(',',$value['channel']);
                $wData[] = " t_user.cur_channel not in ({$curChannel})";
            }

            //版本
            if (!empty($value['version'])) {
                $wData[] = " t_user.version <> '{$value['version']}'";
            }

            //隐藏城市
            $citys = [];
            foreach ($value['hidden_city'] as $hiddenCity) {
                $citys[] = "'.$hiddenCity.'";
            }

            if ($citys) {
                $ct = implode(',',$citys);
                $wData[] = "t_user_profile.city not in($ct)";
            }

            if ($wData) $item[$key] = "(".implode(' and ',$wData).")";
        }
        if($item)  $where .= ' AND (' . implode(' AND ', $item) . ')';
        return $where;

    }

    /**
     * 获取屏蔽条件子查询
     * @param $query
     * @return mixed
     */
    public function getAppHiddenSubQuery($query)
    {
        // 排除屏蔽人员
        $setting = SettingAppHidden::getSetting();
        foreach ($setting as $item => $value) {
            $unionWhere = [];
            $where = " 1 ";

            // 应用ID
//            if (!empty($value['app_id'])) {
//                $app_id = implode(',', $value['app_id']);
//                $unionWhere[] = " t_user.app_id in({$app_id})";
//            }

            // 渠道
            if (!empty($value['channel'])) {
                $curChannel  = implode(',', $value['channel']);
                $unionWhere[] = " t_user.cur_channel in ({$curChannel})";
            }

            // 版本
            if (!empty($value['version'])) {
                $unionWhere[] = " t_user.version = '{$value['version']}'";
            }

            if (!empty($value['hidden_city']) && $value['hidden_un_know_city']) {
                $hiddenCity = "'" . join("','", array_values($value['hidden_city']) ) . "'";
                $unionWhere[] = " (t_user_profile.locate_city in ({$hiddenCity}) or t_user_profile.locate_city = '') ";
            } elseif (!empty($value['hidden_city']) && $value['hidden_un_know_city'] == 0) {
                $hiddenCity = "'" . join("','", array_values($value['hidden_city']) ) . "'";
                $unionWhere[] = " t_user_profile.locate_city in ({$hiddenCity}) ";
            } elseif (empty($value['hidden_city']) && $value['hidden_un_know_city']) {
                $unionWhere[] = " t_user_profile.locate_city = '' ";
            }

            $appHiddenRichValue = env('APP_HIDDEN_RICH_VALUE', 5000);
            $unionWhere[] = " t_user_profile.rich_value <  " . $appHiddenRichValue . ' ';

            $where .= ' AND (' . implode(' AND ', $unionWhere) . ')';

            $query = $query->whereNotIn('user.id', function ($query) use ($where) {
                $query->select('user.id')
                    ->from('user_profile')
                    ->join('user', function ($join) {
                        $join->on('user.id', '=', 'user_profile.user_id');
                    })
                    ->whereRaw($where);
            });
        }

        return $query;
    }

    /**
     * 根据条件获获取check
     * @param $version
     * @param $funcType
     * @return array
     */
    public static function getIsCheckStatusByWhere($version,$funcType): array
    {
        return self::where([
            ['version','=',$version],
            ['func_type','=',$funcType],
            ['flag','=',1]
        ])->get()->toArray();
    }

    /**
     * 判断该模块对该用户是否隐藏
     * @param $userId
     * @param $appId
     * @param $appVersion
     * @param $appChannel
     * @param $funcType
     * @return int 1=屏蔽 0=不用屏蔽
     */
    static function checkModuleHiddenByUser($userId, $appId, $appVersion, $appChannel, $funcType)
    {
        $userProfile = UserProfile::getProfile($userId);
        if (empty($userProfile)) {
            return 0;
        }

        $userCity = $userProfile->locate_city;

        $settings = self::getSetting($funcType);

        $appHiddenRichValue = env('APP_HIDDEN_RICH_VALUE', 5000);

        $flag = 0;
        foreach ($settings as $setting) {
            //屏蔽特定地区
            $cityHidden = true;
            if (!empty($setting['hidden_city']) && $setting['hidden_un_know_city']) {
                if (!(in_array($userCity, $setting['hidden_city']) || empty($userCity))) {
                    $cityHidden = false;
                }
            } elseif (!empty($setting['hidden_city']) && $setting['hidden_un_know_city'] == 0) {
                if (!in_array($userCity, $setting['hidden_city'])) {
                    $cityHidden = false;
                }
            } elseif (empty($setting['hidden_city']) && $setting['hidden_un_know_city']) {
                if (!empty($userCity)) {
                    $cityHidden = false;
                }
            }

            if (in_array($appChannel, $setting['channel'])
                && ($appVersion == $setting['version'])
                && ($userProfile->rich_value < $appHiddenRichValue)
                && $cityHidden
            ) {
                $flag = 1;

                break;
            }
        }

        return $flag;
    }

    /**
     * 加入屏蔽集合
     * @param $userId
     * @return true
     */
    static function addExcludeUserSet($userId)
    {
        $redis = RedisUtil::getRedis();

        $key = RedisKey::appHiddenUser();

        $redis->sAdd($key, $userId);

        log_info(__CLASS__.'==放入屏蔽set==userId:'.$userId);

        return true;
    }

    /**
     * 获取屏蔽的用户
     * @return array
     */
    static function getExcludeUsers()
    {
        $key = RedisKey::appHiddenUser();

        $redis = RedisUtil::getRedis();

        return $redis->sMembers($key);
    }

    /**
     * 检查是否打开礼物开关
     * @param $userId
     * @param $appId
     * @param $appVersion
     * @param $appChannel
     * @param $funcType
     * @return int 1=屏蔽 0=不用屏蔽
     */
    static function checkGiftKgHiddenByUser($appVersion, $appChannel, $funcType)
    {
        $settings = self::getSetting($funcType);

        $flag = 0;
        foreach ($settings as $setting) {
            if (in_array($appChannel, $setting['channel']) && ($appVersion == $setting['version'])) {
                $flag = 1;

                break;
            }
        }

        return $flag;
    }
}
